home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / src / binutils.252 / ld / ldwrite.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-22  |  9.0 KB  |  347 lines

  1. /* ldwrite.c -- write out the linked file
  2.    Copyright (C) 1993 Free Software Foundation, Inc.
  3.    Written by Steve Chamberlain sac@cygnus.com
  4.  
  5. This file is part of GLD, the Gnu Linker.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. #include "bfd.h"
  22. #include "sysdep.h"
  23. #include "bfdlink.h"
  24.  
  25. #include "ld.h"
  26. #include "ldexp.h"
  27. #include "ldlang.h"
  28. #include "ldwrite.h"
  29. #include "ldmisc.h"
  30. #include "ldgram.h"
  31. #include "ldmain.h"
  32.  
  33. static void build_link_order PARAMS ((lang_statement_union_type *));
  34. static void print_symbol_table PARAMS ((void));
  35. static void print_file_stuff PARAMS ((lang_input_statement_type *));
  36. static boolean print_symbol PARAMS ((struct bfd_link_hash_entry *, PTR));
  37.  
  38. /* Build link_order structures for the BFD linker.  */
  39.  
  40. static void
  41. build_link_order (statement)
  42.      lang_statement_union_type *statement;
  43. {
  44.   switch (statement->header.type)
  45.     {
  46.     case lang_data_statement_enum:
  47.       {
  48.     asection *output_section;
  49.     struct bfd_link_order *link_order;
  50.     bfd_vma value;
  51.  
  52.     output_section = statement->data_statement.output_section;
  53.     ASSERT (output_section->owner == output_bfd);
  54.  
  55.     link_order = bfd_new_link_order (output_bfd, output_section);
  56.     if (link_order == NULL)
  57.       einfo ("%P%F: bfd_new_link_order failed");
  58.  
  59.     link_order->type = bfd_data_link_order;
  60.     link_order->offset = statement->data_statement.output_vma;
  61.     link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE);
  62.  
  63.     value = statement->data_statement.value;
  64.  
  65.     ASSERT (output_section->owner == output_bfd);
  66.     switch (statement->data_statement.type)
  67.       {
  68.       case QUAD:
  69.         bfd_put_64 (output_bfd, value, link_order->u.data.contents);
  70.         link_order->size = QUAD_SIZE;
  71.         break;
  72.       case LONG:
  73.         bfd_put_32 (output_bfd, value, link_order->u.data.contents);
  74.         link_order->size = LONG_SIZE;
  75.         break;
  76.       case SHORT:
  77.         bfd_put_16 (output_bfd, value, link_order->u.data.contents);
  78.         link_order->size = SHORT_SIZE;
  79.         break;
  80.       case BYTE:
  81.         bfd_put_8 (output_bfd, value, link_order->u.data.contents);
  82.         link_order->size = BYTE_SIZE;
  83.         break;
  84.       default:
  85.         abort ();
  86.       }
  87.       }
  88.       break;
  89.  
  90.     case lang_reloc_statement_enum:
  91.       {
  92.     lang_reloc_statement_type *rs;
  93.     asection *output_section;
  94.     struct bfd_link_order *link_order;
  95.  
  96.     rs = &statement->reloc_statement;
  97.  
  98.     output_section = rs->output_section;
  99.     ASSERT (output_section->owner == output_bfd);
  100.  
  101.     link_order = bfd_new_link_order (output_bfd, output_section);
  102.     if (link_order == NULL)
  103.       einfo ("%P%F: bfd_new_link_order failed");
  104.  
  105.     link_order->offset = rs->output_vma;
  106.     link_order->size = bfd_get_reloc_size (rs->howto);
  107.  
  108.     link_order->u.reloc.p =
  109.       ((struct bfd_link_order_reloc *)
  110.        xmalloc (sizeof (struct bfd_link_order_reloc)));
  111.  
  112.     link_order->u.reloc.p->reloc = rs->reloc;
  113.     link_order->u.reloc.p->addend = rs->addend_value;
  114.  
  115.     if (rs->section != (asection *) NULL)
  116.       {
  117.         ASSERT (rs->name == (const char *) NULL);
  118.         link_order->type = bfd_section_reloc_link_order;
  119.         if (rs->section->owner == output_bfd)
  120.           link_order->u.reloc.p->u.section = rs->section;
  121.         else
  122.           {
  123.         link_order->u.reloc.p->u.section = rs->section->output_section;
  124.         link_order->u.reloc.p->addend += rs->section->output_offset;
  125.           }
  126.       }
  127.     else
  128.       {
  129.         ASSERT (rs->name != (const char *) NULL);
  130.         link_order->type = bfd_symbol_reloc_link_order;
  131.         link_order->u.reloc.p->u.name = rs->name;
  132.       }
  133.       }
  134.       break;
  135.  
  136.     case lang_input_section_enum:
  137.       /* Create a new link_order in the output section with this
  138.      attached */
  139.       if (statement->input_section.ifile->just_syms_flag == false)
  140.     {
  141.       asection *i = statement->input_section.section;
  142.       asection *output_section = i->output_section;
  143.  
  144.       ASSERT (output_section->owner == output_bfd);
  145.  
  146.       if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
  147.         {
  148.           struct bfd_link_order *link_order;
  149.  
  150.           link_order = bfd_new_link_order (output_bfd, output_section);
  151.  
  152.           if (i->flags & SEC_NEVER_LOAD)
  153.         {
  154.           /* We've got a never load section inside one which
  155.              is going to be output, we'll change it into a
  156.              fill link_order */
  157.           link_order->type = bfd_fill_link_order;
  158.           link_order->u.fill.value = 0;
  159.         }
  160.           else
  161.         {
  162.           link_order->type = bfd_indirect_link_order;
  163.           link_order->u.indirect.section = i;
  164.           ASSERT (i->output_section == output_section);
  165.         }
  166.           if (i->_cooked_size)
  167.         link_order->size = i->_cooked_size;
  168.           else
  169.         link_order->size = bfd_get_section_size_before_reloc (i);
  170.           link_order->offset = i->output_offset;
  171.         }
  172.     }
  173.       break;
  174.  
  175.     case lang_padding_statement_enum:
  176.       /* Make a new link_order with the right filler */
  177.       {
  178.     asection *output_section;
  179.     struct bfd_link_order *link_order;
  180.  
  181.     output_section = statement->padding_statement.output_section;
  182.     ASSERT (statement->padding_statement.output_section->owner
  183.         == output_bfd);
  184.     if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
  185.       {
  186.         link_order = bfd_new_link_order (output_bfd, output_section);
  187.         link_order->type = bfd_fill_link_order;
  188.         link_order->size = statement->padding_statement.size;
  189.         link_order->offset = statement->padding_statement.output_offset;
  190.         link_order->u.fill.value = statement->padding_statement.fill;
  191.       }
  192.       }
  193.       break;
  194.  
  195.     default:
  196.       /* All the other ones fall through */
  197.       break;
  198.     }
  199. }
  200.  
  201. /* Call BFD to write out the linked file.  */
  202.  
  203. void
  204. ldwrite ()
  205. {
  206.   lang_for_each_statement (build_link_order);
  207.  
  208.   if (! bfd_final_link (output_bfd, &link_info))
  209.     einfo ("%F%P: final link failed: %E\n", output_bfd);
  210.  
  211.   if (config.map_file)
  212.     {
  213.       print_symbol_table ();
  214.       lang_map ();
  215.     }
  216. }
  217.  
  218. /* Print the symbol table.  */
  219.  
  220. static void
  221. print_symbol_table ()
  222. {
  223.   fprintf (config.map_file, "**FILES**\n\n");
  224.   lang_for_each_file (print_file_stuff);
  225.  
  226.   fprintf (config.map_file, "**GLOBAL SYMBOLS**\n\n");
  227.   fprintf (config.map_file, "offset    section    offset   symbol\n");
  228.   bfd_link_hash_traverse (link_info.hash, print_symbol, (PTR) NULL);
  229. }
  230.  
  231. /* Print information about a file.  */
  232.  
  233. static void
  234. print_file_stuff (f)
  235.      lang_input_statement_type * f;
  236. {
  237.   fprintf (config.map_file, "  %s\n", f->filename);
  238.   if (f->just_syms_flag)
  239.     {
  240.       fprintf (config.map_file, " symbols only\n");
  241.     }
  242.   else
  243.     {
  244.       asection *s;
  245.       if (true)
  246.     {
  247.       for (s = f->the_bfd->sections;
  248.            s != (asection *) NULL;
  249.            s = s->next)
  250.         {
  251.           print_address (s->output_offset);
  252.           if (s->reloc_done)
  253.         {
  254.           fprintf (config.map_file, " %08x 2**%2ud %s\n",
  255.                (unsigned) bfd_get_section_size_after_reloc (s),
  256.                s->alignment_power, s->name);
  257.         }
  258.  
  259.           else
  260.         {
  261.           fprintf (config.map_file, " %08x 2**%2ud %s\n",
  262.                (unsigned) bfd_get_section_size_before_reloc (s),
  263.                s->alignment_power, s->name);
  264.         }
  265.         }
  266.     }
  267.       else
  268.     {
  269.       for (s = f->the_bfd->sections;
  270.            s != (asection *) NULL;
  271.            s = s->next)
  272.         {
  273.           fprintf (config.map_file, "%s ", s->name);
  274.           print_address (s->output_offset);
  275.           fprintf (config.map_file, "(%x)",
  276.                (unsigned) bfd_get_section_size_after_reloc (s));
  277.         }
  278.       fprintf (config.map_file, "hex \n");
  279.     }
  280.     }
  281.   print_nl ();
  282. }
  283.  
  284. /* Print a symbol.  */
  285.  
  286. /*ARGSUSED*/
  287. static boolean
  288. print_symbol (p, ignore)
  289.      struct bfd_link_hash_entry *p;
  290.      PTR ignore;
  291. {
  292.   while (p->type == bfd_link_hash_indirect
  293.      || p->type == bfd_link_hash_warning)
  294.     p = p->u.i.link;
  295.  
  296.   switch (p->type) 
  297.     {
  298.     case bfd_link_hash_new:
  299.       abort ();
  300.  
  301.     case bfd_link_hash_undefined:
  302.       fprintf (config.map_file, "undefined                     ");
  303.       fprintf (config.map_file, "%s ", p->root.string);
  304.       print_nl ();    
  305.       break;
  306.  
  307.     case bfd_link_hash_weak:
  308.       fprintf (config.map_file, "weak                          ");
  309.       fprintf (config.map_file, "%s ", p->root.string);
  310.       print_nl ();    
  311.       break;
  312.  
  313.     case bfd_link_hash_defined:        
  314.       {
  315.     asection *defsec = p->u.def.section;
  316.  
  317.     print_address (p->u.def.value);
  318.     if (defsec)
  319.       {
  320.         fprintf (config.map_file, "  %-10s",
  321.              bfd_section_name (output_bfd, defsec));
  322.         print_space ();
  323.         print_address (p->u.def.value + defsec->vma);
  324.       }
  325.     else
  326.       {
  327.         fprintf (config.map_file, "         .......");
  328.       }
  329.     fprintf (config.map_file, " %s ", p->root.string);
  330.       }
  331.       print_nl ();    
  332.       break;
  333.  
  334.     case bfd_link_hash_common:
  335.       fprintf (config.map_file, "common               ");
  336.       print_address (p->u.c.size);
  337.       fprintf (config.map_file, " %s ", p->root.string);
  338.       print_nl ();
  339.       break;
  340.  
  341.     default:
  342.       abort ();
  343.     }
  344.  
  345.   return true;
  346. }
  347.